package Vista;
import javax.swing.*;

import Controlador.Controlador;
import Modelo.*;

import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;


public class PantallaJuego implements Observer {
	
	private int f; 
	private int c;
	private  Juego juego;
	private JFrame framePrincipal;
	private JPanel unPanel;
	private JLabel bloquesVisuales[][];
	private Collection<Dibujador> bloques;
	private Collection<Dibujador> habilidades;
	private Collection<DibujadorAccion> acciones;
	ArrayList<Habilidad> h;
	private int nivel;
	private String nombre;
	private Controlador controlador;
	private JLabel boton[];
	
	
	private JLabel cronometro;
	private JLabel vivosPooglins;
	private JLabel aSalvarPooglins;
	private JLabel alojadosPooglins;
	private JLabel indicadorNivel;
	
	public void setControlador(Controlador unControlador){
		controlador = unControlador;
	}

	public PantallaJuego(Juego unJuego){
		
		inicializarEntidades();
		juego= unJuego;
		nivel = unJuego.getNivel();
		nombre= unJuego.getNombre();
		try {
			juego.inicializarNivel(nivel);
		} 
		catch (MapaInvalidoException e) {
			System.out.println(e.mostrarMensaje());
			System.exit(0);
		}
		catch (NivelInexistenteException e) {
			System.out.println("Nivel inexistente");
			System.exit(0);
		}
		h=(ArrayList<Habilidad>) juego.getHabilidades();	
		
		unPanel = new JPanel();
		
		armarPanel();
		inicializarFrame();				
	}

	private void inicializarEntidades() {
		cronometro = new JLabel();
		vivosPooglins = new JLabel();
		aSalvarPooglins = new JLabel();
		alojadosPooglins = new JLabel();
		indicadorNivel = new JLabel(); 
		
		bloques= new ArrayList<Dibujador>();
		bloques.add(new Dibujador("Modelo.Roca", "imagenes/roca.JPG"));
		bloques.add(new Dibujador("Modelo.Tierra", "imagenes/tierra.JPG"));
		bloques.add(new Dibujador("Modelo.Vacio", "imagenes/vacio.JPG"));
		bloques.add(new Dibujador("Modelo.Hielo", "imagenes/hielo.JPG"));
		bloques.add(new Dibujador("Modelo.Fuego", "imagenes/fuego.JPG"));
		bloques.add(new Dibujador("Modelo.NaveEspacial", "imagenes/naveespacial.JPG"));
		bloques.add(new Dibujador("Modelo.NaveEspacialLlegada", "imagenes/naveespacialllegada.JPG"));
		bloques.add(new Dibujador("Modelo.Portal", "imagenes/portal.JPG"));
		bloques.add(new Dibujador("Modelo.AgujeroNegro", "imagenes/agujeronegro.JPG"));
		
		habilidades= new ArrayList<Dibujador>();
		habilidades.add(new Dibujador("Modelo.Laser","imagenes/laser.gif"));
		habilidades.add(new Dibujador("Modelo.Taladro","imagenes/taladro.gif"));
		habilidades.add(new Dibujador("Modelo.Congelamiento","imagenes/congelamiento.gif"));
		habilidades.add(new Dibujador("Modelo.TunelElectromagnetico","imagenes/tunel.gif"));
		habilidades.add(new Dibujador("Modelo.Teletransportacion","imagenes/teletransportacion.gif"));
		habilidades.add(new Dibujador("Modelo.PlatilloVolador","imagenes/platillovolador.gif"));
		
		acciones= new  ArrayList<DibujadorAccion>();
		acciones.add(new DibujadorAccion("Modelo.Laser","imagenes/laserderecha.gif",Constantes.derecha));
		acciones.add(new DibujadorAccion("Modelo.Laser","imagenes/laserizquierda.gif",Constantes.izquierda));
		acciones.add(new DibujadorAccion("Modelo.Laser","imagenes/laserderechaizquierda.gif",Constantes.derechaEIzquierda));
		acciones.add(new DibujadorAccion("Modelo.Laser","imagenes/laserizquierdaderecha.gif",Constantes.IzquierdaYDerecha));
		acciones.add(new DibujadorAccion("Modelo.Taladro","imagenes/taladroderecha.gif",Constantes.derecha));
		acciones.add(new DibujadorAccion("Modelo.Taladro","imagenes/taladroizquierda.gif",Constantes.izquierda));
		acciones.add(new DibujadorAccion("Modelo.Taladro","imagenes/taladroderechaizquierda.gif",Constantes.derechaEIzquierda));
		acciones.add(new DibujadorAccion("Modelo.Taladro","imagenes/taladroderechaizquierda.gif",Constantes.IzquierdaYDerecha));
		acciones.add(new DibujadorAccion("Modelo.PlatilloVolador","imagenes/platilloconbicho.gif",Constantes.derecha));
		acciones.add(new DibujadorAccion("Modelo.PlatilloVolador","imagenes/platilloconbicho.gif",Constantes.izquierda));
	}
	
	private ImageIcon graficar(Bloque bl){
		if(bl instanceof Vacio){
			if(bl.getAlojados().size()>1){
				Iterator<Personaje> ite=bl.getAlojados().iterator();
				int direccion=ite.next().getSentido();
				int dirHab = 0;
				Habilidad hab=null;
				while(ite.hasNext()){
					PoseedorDeHabilidad p= (PoseedorDeHabilidad) ite.next();
					if(p.ejecutoHabilidad()){
						System.out.println("Ejecute " + p.getHabilidad().getClass().getName());
						hab=p.getHabilidad();
						dirHab=p.getSentido();
					}
					if(p.getSentido()!=direccion)
						if(hab==null){
							direccion=Constantes.derechaEIzquierda;
						}
						else{
							if(dirHab==Constantes.derecha)
								direccion=Constantes.derechaEIzquierda;
							else
								direccion=Constantes.IzquierdaYDerecha;
						}
						break;
				}
				if(hab!=null){
					Iterator<DibujadorAccion> iterador= acciones.iterator();
					while(iterador.hasNext()){
						DibujadorAccion a= iterador.next();
						if(a.getNombre()==hab.getClass().getName()&&a.getSentido()==direccion)
							return a.getImagen();
					}
				}
				if(direccion==Constantes.derechaEIzquierda)
					return new ImageIcon("imagenes/vacioconbichoizquierdaderecha.gif");
				if(direccion==Constantes.derecha)
					return new ImageIcon("imagenes/vacioconbichoderecha.gif");
				if(direccion==Constantes.izquierda)
					return new ImageIcon("imagenes/vacioconbichoizquierda.gif");
				return new ImageIcon("imagenes/vacioconbichoizquierdaderecha.gif");
			}
			if(bl.getAlojados().size()==1){	// un solo personaje
				PoseedorDeHabilidad p= (PoseedorDeHabilidad) bl.getAlojados().iterator().next();
				if(p.ejecutoHabilidad()){
					System.out.println("Ejecute " + p.getHabilidad().getClass().getName());
					Iterator<DibujadorAccion> iterador= acciones.iterator();
					while(iterador.hasNext()){
						DibujadorAccion a= iterador.next();
						if(a.getNombre()==p.getHabilidad().getClass().getName()&&a.getSentido()==p.getSentido())
							return a.getImagen();
					}
				}
				if(p.getSentido()==Constantes.derecha)
					return new ImageIcon("imagenes/vacioconbichoderecha.gif");
				return new ImageIcon("imagenes/vacioconbichoizquierda.gif");
			}
		}
		if(bl instanceof Fuego)
			if(bl.getAlojados().size()>0)
				return new ImageIcon("imagenes/fuegoconbicho.gif");		
		String n=bl.getClass().getName();
		Iterator<Dibujador> it= bloques.iterator();
		while(it.hasNext()){
			Dibujador b= it.next();
			if(b.getNombre()==n)
				return b.getImagen();
		}
		return null;
	}
	
	private void rearmarPanel() {
		rearmarPanelHabilidades();
		JPanel otroPanel = new JPanel(new GridLayout(f,1));
		// botones
		int x=0;
		for(int i=0;i<f;i++){
			for(int j=0;j<c;j++){
				Bloque b;
				b=juego.getMapa().getBloque(i, j);
					
				bloquesVisuales[i][j].setIcon(graficar(b));
				x++;
			}
		}
		unPanel.add(otroPanel);
	}
	
	private JLabel botonHabilidad(Dibujador hab){
		int cant=0;
		if(h.size()==0){
			JLabel jBoton = new JLabel("0",hab.getImagen(),0);
			return jBoton;
		}
		Iterator<Habilidad>it= h.iterator();
		Habilidad habilidad=null;
		while(it.hasNext()){
			Habilidad aux= it.next();
			if(aux.getClass().getName()==hab.getNombre()){
				cant++;
				habilidad=aux;
			}
		}		
		JLabel jBoton= new JLabel("" + cant,hab.getImagen(),0); 
		if(habilidad!=null)
			jBoton.addMouseListener(new ProcesoBotonHabilidades(habilidad));
		return jBoton;		
		
		
	}
	
	private void rearmarPanelHabilidades(){
		h=(ArrayList<Habilidad>) juego.getHabilidades();
		
		JPanel panelBotones = new JPanel(new GridLayout(habilidades.size()+2,1));
		Iterator<Dibujador> it= habilidades.iterator();
		int i=0;
		while(it.hasNext()){
			Dibujador hab= it.next();
			Iterator<Habilidad>iter= h.iterator();
			Habilidad habilidad=null;
			int cant=0;
			while(iter.hasNext()){
				Habilidad aux= iter.next();
				if(aux.getClass().getName()==hab.getNombre()){
					cant++;
					habilidad=aux;
				}
			}
			boton[i].setText(""+cant);
			if(habilidad!=null)
				boton[i].addMouseListener(new ProcesoBotonHabilidades(habilidad));
			i++;
		}	
		
		vivosPooglins.setText(juego.pooglinsVivos());
		alojadosPooglins.setText(juego.pooglinsSalvados());
		aSalvarPooglins.setText(juego.pooglinsMin());
		cronometro.setText(juego.tiempoFaltante()); 
		unPanel.add(panelBotones);

	}

	
	private void panelHabilidades(){
		h=(ArrayList<Habilidad>) juego.getHabilidades();
		
		boton= new JLabel[habilidades.size()+2];
		JPanel panelBotones = new JPanel(new GridLayout(habilidades.size()+5,1));
		Iterator<Dibujador> it= habilidades.iterator();
		int i=0;
		while(it.hasNext()){
			Dibujador hab= it.next();
			boton[i]= botonHabilidad(hab);
			panelBotones.add(boton[i]);
			i++;
		}			
		nombre= juego.getNombre();
		cronometro.setText(juego.tiempoFaltante()); 
		vivosPooglins.setText(juego.pooglinsVivos());
		alojadosPooglins.setText(juego.pooglinsSalvados());
		aSalvarPooglins.setText(juego.pooglinsMin());
		indicadorNivel.setText("Nivel: " + juego.getNivel() + " : " + nombre );
		panelBotones.add(cronometro);
		panelBotones.add(vivosPooglins);
		panelBotones.add(alojadosPooglins);
		panelBotones.add(aSalvarPooglins);
		panelBotones.add(indicadorNivel);
		unPanel.add(panelBotones);
		
	}
	
	private void armarPanel() {
		panelHabilidades();
		
		f=juego.getMapa().getMaxEjeX();
		c=juego.getMapa().getMaxEjeY();
		JPanel otroPanel = new JPanel(new GridLayout(f,1));
		// botones
		bloquesVisuales= new JLabel[f][c];
		for(int i=0;i<f;i++){
			for(int j=0;j<c;j++){
				Bloque b;
				b=juego.getMapa().getBloque(i, j);
					
				bloquesVisuales[i][j]= new  JLabel(graficar(b));
				
				bloquesVisuales[i][j].setBorder(null);
				/*Agrego una posicion de localizacion  a los bloquesvisuales**/
				bloquesVisuales[i][j].addMouseListener(new EscucharMouse());
				
				otroPanel.add(bloquesVisuales[i][j]);
			}
		}			
		unPanel.add(otroPanel);
	}

	private void inicializarFrame() {

		framePrincipal = new JFrame();
		
		framePrincipal.getContentPane().removeAll();
		framePrincipal.setMenuBar(null);
		framePrincipal.setSize(new Dimension(25*f,25*c));

		
		framePrincipal.setLocation(0, 0);
		
		
		framePrincipal.setContentPane(unPanel);
		framePrincipal.addWindowListener(new MonitorVentanaBasica());
		framePrincipal.setVisible(true);
		nivel = juego.getNivel();
		framePrincipal.setTitle("Pooglins! --- Nivel " + nivel );
		framePrincipal.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		framePrincipal.setResizable(false);
		
		
		JMenuBar barraMenu = new JMenuBar();
		JMenu menuJuego = new JMenu("Juego");
		
		JMenuItem itemMenuReiniciar = new JMenuItem("Reiniciar");		
		menuJuego.add(itemMenuReiniciar);
		itemMenuReiniciar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	
            	framePrincipal.setVisible(false);
            	controlador.terminarJuego();
            	           	
            	Juego juego = new Juego("niveles/listaniveles.xml");
            	try{
            		juego.cargarJuego("niveles/salvado.xml");
            		}
            		catch (MapaInvalidoException e1){
            			
            		}
            		catch (NivelInexistenteException e2){
            			
            		}
        		PantallaJuego vista =new PantallaJuego(juego);
        		Controlador unControladorAuto = new Controlador(juego,vista);
        		vista.setControlador(unControladorAuto);
        		
            }
        });
		
		JMenuItem itemMenuSalir = new JMenuItem("Salir");		
		menuJuego.add(itemMenuSalir);
        itemMenuSalir.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            	System.exit(0);
            }
        });
		
		barraMenu.add(menuJuego);
		framePrincipal.setJMenuBar(barraMenu);
		framePrincipal.pack();
	}

	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		
	}
	
	public void update() {
		rearmarPanel();
	}
	// de esta forma, podemos acceder al los atributos d la vista, ej: juego
	private class EscucharMouse implements MouseListener{
		
		// Evento con el mouse
		public void mouseClicked(MouseEvent e) {
			//Apretaste este bloque
			JLabel evento = (JLabel)e.getSource();
			// factor de division de bloques , si es 25 pix => k=26
			int k= 25;
			
			int fila = ((int)(evento.getLocation().getY()))/k;
			int columna = ((int)evento.getLocation().getX())/k;
			  
			// luego le pasamos al controlador, el personaje q se marco para asignarle la habilidad
			controlador.asignarHabilidadA(fila , columna);
		}

		public void mouseEntered(MouseEvent e) {
		}
		public void mouseExited(MouseEvent e) {
		}
		public void mousePressed(MouseEvent e) {
		}
		public void mouseReleased(MouseEvent e) {
		}
	}
	
	private class ProcesoBotonHabilidades extends MouseAdapter{
		Habilidad habilidad;
		
		public ProcesoBotonHabilidades(Habilidad hab){
			habilidad = hab;
		}

		// Evento con el mouse
		public void mouseClicked(MouseEvent e) {
			//asigna la habilidad
			controlador.tomarHabilidad(this.habilidad);
		}
	}

	public void resultado(boolean ganado) {
		if (ganado)
			pasarAlSiguienteNivel();
		else
			FinDelJuego(".........Game Over.........");
	}

	private void FinDelJuego(String msg) {
		controlador.terminarJuego();
		
		final JOptionPane optionPane = new JOptionPane(
                msg,
                JOptionPane.WARNING_MESSAGE,
                JOptionPane.CLOSED_OPTION);

		final JDialog dialog = new JDialog(this.framePrincipal,
                "  XDD  ",
                true);
		dialog.setContentPane(optionPane);
		dialog.setDefaultCloseOperation(
				JDialog.DO_NOTHING_ON_CLOSE);
		
		 optionPane.addPropertyChangeListener(
                 new PropertyChangeListener() {
                     public void propertyChange(PropertyChangeEvent e) {
                         String prop = e.getPropertyName();

                         if (dialog.isVisible()
                          && (e.getSource() == optionPane)
                          && (JOptionPane.VALUE_PROPERTY.equals(prop))) {
                             dialog.setVisible(false);
                         }
                     }
                 });

		
		dialog.pack();
		dialog.setDefaultCloseOperation(dialog.HIDE_ON_CLOSE);
        dialog.setLocationRelativeTo(this.framePrincipal);
        dialog.setVisible(true);

	}

	private void pasarAlSiguienteNivel() {
		try{
			juego.siguienteNivel();

			framePrincipal.setVisible(false);
			this.armarPanel();
						
			h=(ArrayList<Habilidad>) juego.getHabilidades();	
			unPanel = new JPanel();
			armarPanel();
			inicializarFrame();	
			salvarPuntoDePartida();
			controlador.reiniciar();
		}
		catch (MapaInvalidoException e){
			System.out.println("Falta el mapa del nivel ");
			System.exit(1);
		}
		catch (NivelInexistenteException e){			
			System.out.println("El nivel no existe : ");
			FinDelJuego(".........YOU ARE A CHAMPION.........");
			new PantallaInicial();
			framePrincipal.setVisible(false);
		}
	}

	private void salvarPuntoDePartida() {
		juego.guardarJuego("niveles/salvado.xml");
	}
	
	

}
